Android View的22500行源码分析系列(一)setFlag 方法,setVisibilty,setFoucus,setEnable等方法内部实现

一直想系统地学习Android源码,最近又计划写一个自定义控件系列的博客,而在自定义控件的过程中,许多技巧和方法需要你在Android View,ViewGroup的源码中得到灵感。因此,这一个View的22500行源码分析系列就诞生了偷笑偷笑,本系列基于api23的View的源码,主要是对源码的注解作一些翻译和简单的总结,目的是让大家了解整个View的工

作流程,一些主要方法实现里面的细节问题。说时迟那时快,老司机开车啦,赶紧上车微笑


首先我们看一下View常用的几个方法:

@RemotableViewMethod
public void setVisibility(@Visibility int visibility) {
    setFlags(visibility, VISIBILITY_MASK);
}
public void setFocusable(boolean focusable) {
    if (!focusable) {
        setFlags(0, FOCUSABLE_IN_TOUCH_MODE);
    }
    setFlags(focusable ? FOCUSABLE : NOT_FOCUSABLE, FOCUSABLE_MASK);
}
public void setEnabled(boolean enabled) {
    if (enabled == isEnabled()) return;

    setFlags(enabled ? ENABLED : DISABLED, ENABLED_MASK);

    /*
     * The View most likely has to change its appearance, so refresh
     * the drawable state.
	视图大多数可能改变它的样子,所以刷新drawable的状态
     */
    refreshDrawableState();

    // Invalidate too, since the default behavior for views is to be
    // be drawn at 50% alpha rather than to change the drawable.
	//同时也要刷新,因为默认的View enable为false的行为是透明度为原来的50%而不是改变drawable
    invalidate(true);

    if (!enabled) {
        cancelPendingInputEvents();
    }
}
兄弟们,看见没,看见没!这三个方法里面都会调用关键的setFlags()方法,这方法到底是何方神圣!让我们慢慢揭开其神秘的面纱吧生气
   
   
   
/**
* Set flags controlling behavior of this view.
*设置标记来控制视图的状态
*
* @param flags Constant indicating the value which should be set 表示应该要被设置的值常量
* @param mask Constant indicating the bit range that should be changed 表示应该要被改变的位的常量
*/
该函数在View中多处被调用,例如 View.setEnable()、View.setClickable(),setFocusable()等很多函数都调用到该函数。
在View中使用mViewFlags和mPrivateFlags变量保存大多数的属性:
– mViewFlags:该标记用来保存和视图状态相关的属性。
– mPrivateFlags 该标记用来保存和内部逻辑相关的属性
如Visible相关的Flag:
public static final int VISIBLE = 0x00000000;
public static final int INVISIBLE = 0x00000004;
public static final int GONE = 0x00000008;
static final int VISIBILITY_MASK = 0x0000000C;


void setFlags(int flags, int mask) {
final boolean accessibilityEnabled =
AccessibilityManager.getInstance(mContext).isEnabled();
final boolean oldIncludeForAccessibility = accessibilityEnabled && includeForAccessibility();

int old = mViewFlags;//记录原来的视图状态标记
mViewFlags = (mViewFlags & ~mask) | (flags & mask);//更新视图状态标记

int changed = mViewFlags ^ old;//异或判断状态是否发生改变
if (changed == 0) {//如果没有改变,立刻返回
return;
}
int privateFlags = mPrivateFlags;//记录当前逻辑属性标记

/* Check if the FOCUSABLE bit has changed */ 检查Focusable位有没有改变
if (((changed & FOCUSABLE_MASK) != 0) &&
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值